package com.xbongbong.pro.service.market.statistics.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.service.market.statistics.MarketActivity4StaticHandle;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.StaticForMarketActivityEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @Auther: yingjianfeng
 * @Date: 2022/3/15 14:38
 * @Description:
 */
@Slf4j
public abstract class AbstractMarketActivity4StaticHandle implements MarketActivity4StaticHandle {
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private EsHelper esHelper;


    public BoolQueryBuilder getBaseBoolQueryBuilder(String corpid, IndexTypeEnum indexTypeEnum) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        return boolQueryBuilder;
    }

    public void getDelIds(Collection<Long> delIds, SearchSourceBuilder sourceBuilder, SearchRequest searchRequest, long count) throws XbbException {
        for (int i = 0; i <= count / 100; i++) {
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, i + 1, 100);
            XbbAggregatedPage<StaticForMarketActivityEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, StaticForMarketActivityEntity.class);
            List<StaticForMarketActivityEntity> content = esEntities.getContent();
            for (StaticForMarketActivityEntity item : content) {
                delIds.add(item.getDataId());
            }
        }
    }

    public void getDelIds(Collection<Long> delIds, SearchSourceBuilder sourceBuilder, SearchRequest searchRequest, long count, Set<Long> customerIdIn) throws XbbException {
        for (int i = 0; i <= count / 100; i++) {
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, i + 1, 100);
            XbbAggregatedPage<StaticForMarketActivityEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, StaticForMarketActivityEntity.class);
            List<StaticForMarketActivityEntity> content = esEntities.getContent();
            for (StaticForMarketActivityEntity item : content) {
                delIds.add(item.getDataId());
                if(Objects.nonNull(item.getCustomerId())){
                    customerIdIn.add(item.getCustomerId());
                }
            }
        }
    }
    public void getDelIds(Collection<Long> delIds, SearchSourceBuilder sourceBuilder, SearchRequest searchRequest, long count, Map<Long, Set<Long>> marketIdAndSet) throws XbbException {
        for (int i = 0; i <= count / 100; i++) {
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, i + 1, 100);
            XbbAggregatedPage<StaticForMarketActivityEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, StaticForMarketActivityEntity.class);
            List<StaticForMarketActivityEntity> content = esEntities.getContent();
            for (StaticForMarketActivityEntity item : content) {
                delIds.add(item.getDataId());
                if (marketIdAndSet.containsKey(item.getMarketId())) {
                    marketIdAndSet.get(item.getMarketId()).add(item.getDataId());
                } else {
                    Set<Long> set = new HashSet<>();
                    set.add(item.getDataId());
                    marketIdAndSet.put(item.getMarketId(), set);
                }
            }
        }
    }
    /**
     * 根据attr不同，封装的数据不同
     *
     * @param idIn
     * @param attr
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<Long, StaticForMarketActivityEntity> getMarketEntity(List<Long> idIn, String attr, String corpid) throws XbbException {
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder1.filter(termsQuery(attr, idIn));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        Map<Long, StaticForMarketActivityEntity> entityMap = new HashMap<>(idIn.size());
        list.forEach(item -> {
            if (!entityMap.containsKey(item.getMarketId())) {
                entityMap.put(item.getMarketId(), item);
            }
        });
        return entityMap;
    }

    public Set<Long> getTagetIds(List<Long> idIn, String corpid, IndexTypeEnum indexTypeEnum, String attr) throws XbbException {
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.DELETE.getDel()));
        boolQueryBuilder1.filter(termsQuery(attr, idIn));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        Set<Long> marketIds = new HashSet<>();
        if (Objects.equals(attr, "clueId")) {
            list.forEach(item -> {
                marketIds.add(item.getMarketId());
            });
        }
        if (Objects.equals(attr, "customerId")) {
            list.forEach(item -> {
                marketIds.add(item.getClueId());
            });
        }
        return marketIds;
    }

    public List<Long> getNeedToDeleteId(Collection<Long> idIn, String corpid, String attr) throws XbbException {
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder1.filter(termsQuery(attr, idIn));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        List<Long> needToDelete = new ArrayList<>();
        if (Objects.equals(attr, "marketId")) {
            for (StaticForMarketActivityEntity staticForMarketActivityEntity : list) {
                if (Objects.isNull(staticForMarketActivityEntity.getClueId())) {
                    needToDelete.add(staticForMarketActivityEntity.getDataId());
                }
            }
        }

        if (Objects.equals(attr, "clueId")) {
            for (StaticForMarketActivityEntity staticForMarketActivityEntity : list) {
                if (Objects.isNull(staticForMarketActivityEntity.getCustomerId())) {
                    needToDelete.add(staticForMarketActivityEntity.getDataId());
                }
            }
        }
        return needToDelete;
    }

    /**
     * 获取需要重新建的值
     *
     * @param ids
     * @param count
     * @param attr
     * @param corpid
     * @param field  聚合主键
     * @return
     * @throws XbbException
     */
    public List<Long> getFlag2AddNewData(Collection<Long> ids, long count, String attr, String corpid, String field) throws XbbException {
        // todo 这里有bug，需要重新梳理
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        boolQueryBuilder.filter(termsQuery(attr, ids));
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("aggs01").field(field).order(BucketOrder.key(false));
        termsAggregationBuilder.size(Integer.MAX_VALUE);
        JSONObject resultJsonObject = esHelper.elasticAggs4Buckets2Object(IndexTypeEnum.IDX_STATICS_MARKET_DATA, boolQueryBuilder, termsAggregationBuilder);
        JSONArray bucketsArray = resultJsonObject.getJSONArray("buckets");
        List<Long> marketIds = new ArrayList<>();
        for (Object o : bucketsArray) {
            if (o != null) {
                JSONObject json = (JSONObject) o;
                Long aLong = json.getLong("key");
                Integer doc_count = json.getInteger("doc_count");
                if (Objects.nonNull(doc_count) && doc_count >= BasicConstant.ONE) {
                    marketIds.add(aLong);
                }
            }
        }
        return marketIds;

    }

    /**
     * 主要逻辑是  判断你此次删除的市场活动下的id大小和现有的大小是否一致   一致的话代表删除完了   得新建
     * date: 2022/3/24 4:54 下午
     *
     * @param corpid:
     * @param entityMap:      要删除的市场活动
     * @param marketIdAndSet: key 市场活动   set为此次删除的图表的id
     * @author yingjf
     */
    public List<Long> getAddNewData(String corpid, Map<Long, StaticForMarketActivityEntity> entityMap,
                                    Map<Long, Set<Long>> marketIdAndSet) throws XbbException {
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        List<Long> flag2AddNewData = new ArrayList<>();
        // 查询各个市场活动的图表中心的
        Set<Long> marketIds = new HashSet<>();
        for (Long marketId : entityMap.keySet()) {
            marketIds.add(marketId);
        }
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder1.filter(termsQuery("marketId", marketIds));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        Map<Long, Set<Long>> allMarketIdAndSet = new HashMap<>(list.size());
        for (StaticForMarketActivityEntity item : list) {
            if (allMarketIdAndSet.containsKey(item.getMarketId())) {
                allMarketIdAndSet.get(item.getMarketId()).add(item.getDataId());
            } else {
                Set<Long> set = new HashSet<>();
                set.add(item.getDataId());
                allMarketIdAndSet.put(item.getMarketId(), set);
            }
        }
        for (Long marketId : marketIdAndSet.keySet()) {
            Set<Long> needDelIds = marketIdAndSet.get(marketId);
            Set<Long> allIds = allMarketIdAndSet.get(marketId);
            if (CollectionUtils.isNotEmpty(needDelIds) && CollectionUtils.isNotEmpty(allIds) && Objects.equals(needDelIds.size(), allIds.size())) {
                flag2AddNewData.add(marketId);
            }
        }
        return flag2AddNewData;
    }

    public List<Long> getFlag2AddNewData(Set<Long> customerIdIn, String corpid) throws XbbException {
        List<Long> res = new ArrayList<>();
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder1.filter(termsQuery("customerId", customerIdIn));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        Map<Long, Integer> map = new HashMap();
        for (StaticForMarketActivityEntity temp : list) {
            Long customerId = temp.getCustomerId();
            Integer i = map.get(customerId);
            if(Objects.nonNull(customerId)){
                if (map.containsKey(customerId)) {
                    map.put(customerId, i + 1);
                } else {
                    map.put(customerId, 1);
                }
            }
        }
        for (Long temp : map.keySet()) {
            Integer i = map.get(temp);
            if (Objects.equals(i, 1)) {
                res.add(temp);
            }
        }
        return res;
    }


    public List<Long> getContractFlag2AddNewData(Set<Long> customerIdIn, String corpid) throws XbbException {
        List<Long> res = new ArrayList<>();
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
        boolQueryBuilder1.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder1.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        boolQueryBuilder1.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder1.filter(termsQuery("customerId", customerIdIn));
        List<StaticForMarketActivityEntity> list = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder1, StaticForMarketActivityEntity.class, null);
        Map<Long, Integer> map = new HashMap();
        for (StaticForMarketActivityEntity temp : list) {
            Long customerId = temp.getCustomerId();
            Integer i = map.get(customerId);
            if(Objects.nonNull(customerId)){
                if (map.containsKey(customerId)) {
                    map.put(customerId, i + 1);
                } else {
                    map.put(customerId, 1);
                }
            }
        }
        for (Long temp : map.keySet()) {
            Integer i = map.get(temp);
            if (Objects.equals(i, 1)) {
                res.add(temp);
            }
        }
        return res;
    }

}
